home *** CD-ROM | disk | FTP | other *** search
- /* POP3 Server state machine - see RFC 1225
- *
- * Jan 92 Erik Olson olson@phys.washington.edu
- * Taken from POP2 server code in NOS 910618
- * Rewritten/converted to POP3
- * Feb 92 William Allen Simpson
- * integrated with current work
- * Aug-Oct 92 Mike Bilow, N1BEE, mikebw@ids.net
- * Extensive bug fixes; changed uses of Borland stat()
- * to fsize() in order to fix intermittent crashes;
- * corrected confusion of sockmode()
- *
- * "Need-to" list: XTND XMIT (to get WinQVTnet to work)
- */
-
- #include <stdio.h>
- #include <fcntl.h>
- #include <time.h>
- #include <sys/stat.h>
- #ifdef UNIX
- #include <sys/types.h>
- #endif
- #if defined(__STDC__) || defined(__TURBOC__)
- #include <stdarg.h>
- #endif
- #include <ctype.h>
- #include <setjmp.h>
- #include "global.h"
- #include "mbuf.h"
- #include "cmdparse.h"
- #include "socket.h"
- #include "proc.h"
- #include "files.h"
- #include "smtp.h"
- #include "dirutil.h"
-
- #ifdef POP3SERVER
-
- /* ---------------- common server data structures ---------------- */
- /* POP message pointer element */
-
- struct pop_msg {
- long len;
- long pos;
- int deleted;
- struct pop_msg *next;
- };
-
- /* POP server control block */
-
- struct pop_scb {
- int socket; /* socket number for this connection */
- char state; /* server state */
- #define LSTN 0
- #define AUTH 1
- #define TRANS 2
- #define UPDATE 3
- #define DONE 5
-
- char buf[TLINELEN]; /* input line buffer */
- char count; /* line buffer length */
- char username[64]; /* user/folder name */
- FILE *wf; /* work folder file pointer */
- int folder_len; /* number of msgs in current folder */
- int high_num; /* highest message number accessed */
- long folder_file_size; /* length of the current folder file, in bytes */
- char folder_modified; /* mail folder contents modified flag */
- struct pop_msg *msg; /* message database link-list */
- };
-
- #define NULLSCB (struct pop_scb *)0
-
- /* Response messages -- '\n' is converted to '\r\n' by the socket code */
-
- static char count_rsp[] = "+OK you have %d messages\n",
- error_rsp[] = "-ERR %s\n",
- greeting_msg[] = "+OK %s POP3 ready\n",
- user_rsp[] = "+OK user\n",
- #if 0
- pass_rsp[] = "+OK password\n",
- #endif
- stat_rsp[] = "+OK %d %ld\n",
- list_single_rsp[] = "+OK %d %d\n",
- list_multi_rsp[] = "+OK %d messages (%ld octets)\n",
- retr_rsp[] = "+OK %ld octets\n",
- multi_end_rsp[] = ".\n",
- dele_rsp[] = "+OK message %d deleted\n",
- noop_rsp[] = "+OK\n",
- last_rsp[] = "+OK %d\n",
- signoff_msg[] = "+OK Bye, bye-bye, bye now, goodbye\n";
-
- static void rrip __ARGS((char *s));
- static struct pop_scb *create_scb __ARGS((void));
- static void delete_scb __ARGS((struct pop_scb *scb));
- static void popserv __ARGS((int s,void *unused,void *p));
- static int poplogin __ARGS((char *pass,char *username));
-
- static void pop_sm __ARGS((struct pop_scb *scb));
-
- static int Spop = -1; /* prototype socket for service */
-
-
- /* Start up POP receiver service */
- int
- #ifdef PROTOTYPES
- pop3start(int argc,char **argv,void *p)
- #else
- pop3start(argc,argv,p)
-
- int argc;
- char *argv[];
- void *p;
- #endif
-
- {
- struct sockaddr_in lsocket;
- int s;
-
- if (Spop != -1) {
- return 0;
- }
-
- psignal(Curproc,0); /* Don't keep the parser waiting */
- chname(Curproc,"POP3 listener");
-
- lsocket.sin_family = AF_INET;
- lsocket.sin_addr.s_addr = INADDR_ANY;
- if(argc < 2)
- lsocket.sin_port = IPPORT_POP3;
- else
- lsocket.sin_port = atoi(argv[1]);
-
- Spop = socket(AF_INET,SOCK_STREAM,0);
-
- bind(Spop,(char *)&lsocket,sizeof(lsocket));
-
- listen(Spop,1);
-
- for (;;) {
- if((s = accept(Spop,NULLCHAR,(int *)NULL)) == -1)
- break; /* Service is shutting down */
-
- /* Spawn a server */
-
- newproc("POP3 server",2048,popserv,s,NULL,NULL,0);
- }
- return 0;
- }
-
- /* Shutdown POP3 service (existing connections are allowed to finish) */
-
- int
- #ifdef PROTOTYPES
- pop3stop(int argc,char **argv,void *p)
- #else
- pop3stop(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- #endif
-
- {
- if(Spop != -1) {
- close_s(Spop);
- Spop = -1;
- } else
- tprintf("No POP3 listener to stop\n");
- return 0;
- }
-
- static void
- popserv(s,unused,p)
- int s;
- void *unused;
- void *p;
- {
- struct pop_scb *scb;
- char *cp;
-
- sockowner(s,Curproc); /* We own it now */
- log(s,"open POP3");
-
- if((scb = create_scb()) == NULLSCB) {
- tprintf(Nospace);
- log(s,"close POP3 - no space");
- close_s(s);
- return;
- }
-
- scb->socket = s;
- scb->state = AUTH;
-
- sockmode(s,SOCK_ASCII); /* N1BEE */
- (void) usprintf(s,greeting_msg,Hostname);
-
- loop: if ((scb->count = recvline(s,scb->buf,TLINELEN)) == -1){
- /* He closed on us */
-
- goto quit;
- }
-
- rip(scb->buf);
- if (strlen(scb->buf) == 0) /* Ignore blank cmd lines */
- goto loop;
-
- /* Convert lower, and mixed case commands to UPPER case - Ashok */
- for(cp = scb->buf;*cp != ' ' && *cp != '\0';cp++)
- *cp = toupper(*cp);
-
- pop_sm(scb);
- if (scb->state == DONE)
- goto quit;
-
- goto loop;
-
- quit:
- log(scb->socket,"close POP3");
- close_s(scb->socket);
- delete_scb(scb);
- }
-
-
- /* Create control block, initialize */
-
- static struct
- pop_scb *create_scb()
- {
- register struct pop_scb *scb;
-
- if((scb = (struct pop_scb *)callocw(1,sizeof (struct pop_scb))) == NULLSCB)
- return NULLSCB;
-
- scb->username[0] = '\0';
- scb->msg = NULL;
- scb->wf = NULL;
-
- scb->count = scb->folder_file_size = 0;
-
- scb->folder_modified = FALSE;
- return scb;
- }
-
-
- /* Free msg link-list */
- static void
- delete_msglist(struct pop_msg *b_msg)
- {
- struct pop_msg *msg,*msg2;
- msg=b_msg;
- while(msg!=NULL) {msg2=msg->next; free(msg); msg=msg2;}
- }
-
- /* Free resources, delete control block */
-
- static void
- delete_scb(scb)
- register struct pop_scb *scb;
- {
- if (scb == NULLSCB)
- return;
- if (scb->wf != NULL)
- fclose(scb->wf);
- if (scb->msg != NULL)
- delete_msglist(scb->msg);
-
- free((char *)scb);
- }
-
- /* replace terminating end of line marker(s) (\r and \n) with null,
- and change . to .. */
- static void
- rrip(s)
- register char *s;
- {
- register char *cp;
-
- if((cp = strchr(s,'\r')) != NULLCHAR)
- *cp = '\0';
- if((cp = strchr(s,'\n')) != NULLCHAR)
- *cp = '\0';
- }
-
- /* --------------------- start of POP server code ------------------------ */
-
- #define BITS_PER_WORD 16
-
- #define isSOM(x) ((strncmp(x,"From ",5) == 0))
-
- /* Command string specifications */
-
- static char
- user_cmd[] = "USER ",
- pass_cmd[] = "PASS ",
- quit_cmd[] = "QUIT",
- stat_cmd[] = "STAT",
- list_cmd[] = "LIST",
- retr_cmd[] = "RETR",
- dele_cmd[] = "DELE",
- noop_cmd[] = "NOOP",
- rset_cmd[] = "RSET",
- top_cmd[] = "TOP",
- last_cmd[] = "LAST";
-
- static void
- pop_sm(scb)
- struct pop_scb *scb;
- {
- char password[40];
-
- #ifndef __TURBOC__
- static
- #endif
- void state_error(struct pop_scb *,char *);
- #ifndef __TURBOC__
- static
- #endif
- void fatal_error(struct pop_scb *,char *);
- #ifndef __TURBOC__
- static
- #endif
- void open_folder(struct pop_scb *);
- #ifndef __TURBOC__
- static
- #endif
- void do_cleanup(struct pop_scb *);
- #ifndef __TURBOC__
- static
- #endif
- void stat_message(struct pop_scb *);
- #ifndef __TURBOC__
- static
- #endif
- void list_message(struct pop_scb *);
- #ifndef __TURBOC__
- static
- #endif
- void retr_message(struct pop_scb *);
- #ifndef __TURBOC__
- static
- #endif
- void dele_message(struct pop_scb *);
- #ifndef __TURBOC__
- static
- #endif
- void noop_message(struct pop_scb *);
- #ifndef __TURBOC__
- static
- #endif
- void last_message(struct pop_scb *);
- #ifndef __TURBOC__
- static
- #endif
- void rset_message(struct pop_scb *);
- #ifndef __TURBOC__
- static
- #endif
- void top_message(struct pop_scb *);
- #ifndef __TURBOC__
- static
- #endif
- void close_folder(struct pop_scb *);
-
- if (scb == NULLSCB) /* be certain it is good -- wa6smn */
- return;
-
- switch(scb->state) {
-
- case AUTH:
- if (strncmp(scb->buf,user_cmd,strlen(user_cmd)) == 0){
- sscanf(scb->buf,"USER %s",scb->username);
- (void) usprintf(scb->socket,user_rsp);
-
- } else if (strncmp(scb->buf,pass_cmd,strlen(pass_cmd)) == 0){
- sscanf(scb->buf,"PASS %s",password);
-
- if (!poplogin(scb->username,password)) {
- log(scb->socket,"POP3 access DENIED to %s",
- scb->username);
- state_error(scb,"Access DENIED!!");
- return;
- }
-
- log(scb->socket,"POP3 access granted to %s",
- scb->username);
- open_folder(scb);
- } else if (strncmp(scb->buf,quit_cmd,strlen(quit_cmd)) == 0){
- do_cleanup(scb);
- } else
- state_error(scb,"(AUTH) expected USER, PASS or QUIT");
- break;
-
- case TRANS:
- if (strncmp(scb->buf,stat_cmd,strlen(stat_cmd)) == 0)
- stat_message(scb);
-
- else if (strncmp(scb->buf,list_cmd,strlen(list_cmd)) == 0)
- list_message(scb);
-
- else if (strncmp(scb->buf,retr_cmd,strlen(retr_cmd)) == 0)
- retr_message(scb);
-
- else if (strncmp(scb->buf,dele_cmd,strlen(dele_cmd)) == 0)
- dele_message(scb);
-
- else if (strncmp(scb->buf,last_cmd,strlen(noop_cmd)) == 0)
- noop_message(scb);
-
- else if (strncmp(scb->buf,last_cmd,strlen(last_cmd)) == 0)
- last_message(scb);
-
- else if (strncmp(scb->buf,top_cmd,strlen(top_cmd)) == 0)
- top_message(scb);
-
- else if (strncmp(scb->buf,rset_cmd,strlen(rset_cmd)) == 0)
- rset_message(scb);
-
- else if (strncmp(scb->buf,quit_cmd,strlen(quit_cmd)) == 0)
- do_cleanup(scb);
-
- else
- state_error(scb,
- "(TRANS) unsupported/unrecognized command");
- break;
-
- case DONE:
- break;
-
- default:
- fatal_error(scb,"(TOP) State Error!!");
- break;
- }
- }
-
- static void
- #ifdef PROTOTYPES
- do_cleanup(struct pop_scb *scb)
- #else
- do_cleanup(scb)
- struct pop_scb *scb;
- #endif
- {
- #ifndef __TURBOC__
- static
- #endif
- void close_folder(struct pop_scb *);
-
- close_folder(scb);
- (void) usprintf(scb->socket,signoff_msg);
- scb->state = DONE;
- }
-
- static void
- #ifdef PROTOTYPES
- state_error(struct pop_scb *scb,char *msg)
- #else
- state_error(scb,msg)
- struct pop_scb *scb;
- char *msg;
- #endif
- {
- (void) usprintf(scb->socket,error_rsp,msg);
- /* scb->state = DONE; */ /* Don't automatically hang up */
- }
-
- static void
- #ifdef PROTOTYPES
- fatal_error(struct pop_scb *scb,char *msg)
- #else
- fatal_error(scb,msg)
- struct pop_scb *scb;
- char *msg;
- #endif
- {
- (void) usprintf(scb->socket,error_rsp,msg);
- scb->state = DONE;
- }
-
- static void
- #ifdef PROTOTYPES
- close_folder(struct pop_scb *scb)
- #else
- close_folder(scb)
- struct pop_scb *scb;
- #endif
- {
- char folder_pathname[64];
- char line[TLINELEN];
- FILE *fd;
- int deleted = FALSE;
- int msg_no = 0;
- struct pop_msg *msg;
- #ifndef __TURBOC__
- static
- #endif
- int newmail(struct pop_scb *);
- #ifndef __TURBOC__
- static
- #endif
- void state_error(struct pop_scb *,char *);
- #ifndef __TURBOC__
- static
- #endif
- void fatal_error(struct pop_scb *,char *);
-
-
- if (scb->wf == NULL)
- return;
-
- if (!scb->folder_modified) {
- /* no need to re-write the folder if we have not modified it */
-
- fclose(scb->wf);
- scb->wf = NULL;
-
- delete_msglist(scb->msg);
- scb->msg=NULL;
- return;
- }
-
-
- sprintf(folder_pathname,"%s/%s.txt",Mailspool,scb->username);
-
- if (newmail(scb)) {
- /* copy new mail into the work file and save the
- message count for later */
-
- if ((fd = fopen(folder_pathname,"r")) == NULL) {
- fatal_error(scb,"Unable to add new mail to folder");
- return;
- }
-
- fseek(scb->wf,0,SEEK_END);
- fseek(fd,scb->folder_file_size,SEEK_SET);
- while (!feof(fd)) {
- fgets(line,TLINELEN,fd);
- fputs(line,scb->wf);
- }
-
- fclose(fd);
- }
-
- /* now create the updated mail folder */
-
- if ((fd = fopen(folder_pathname,"w")) == NULL){
- fatal_error(scb,"Unable to update mail folder");
- return;
- }
-
- rewind(scb->wf);
- msg=scb->msg;
- while (!feof(scb->wf)){
- fgets(line,TLINELEN,scb->wf);
-
- if (isSOM(line)){
- if (msg!=NULL) msg=msg->next;
- msg_no++;
- if (msg!=NULL)
- deleted = msg->deleted;
- else
- deleted = FALSE;
- }
-
- if (deleted)
- continue;
-
- fputs(line,fd);
- }
-
- fclose(fd);
- fclose(scb->wf);
- scb->wf = NULL;
- delete_msglist(scb->msg);
- scb->msg=NULL;
-
- }
-
- static void
- #ifdef PROTOTYPES
- open_folder(struct pop_scb *scb)
- #else
- open_folder(scb)
- struct pop_scb *scb;
- #endif
- {
- char folder_pathname[64];
- char line[TLINELEN];
- long pos;
- FILE *fd;
- FILE *tmpfile __ARGS((void));
- struct stat folder_stat;
- struct pop_msg *msg;
-
- sprintf(folder_pathname,"%s/%s.txt",Mailspool,scb->username);
- scb->folder_len = 0;
- scb->folder_file_size = 0;
- /* if (stat(folder_pathname,&folder_stat)){ */
- if((folder_stat.st_size = fsize(folder_pathname)) == -1) { /* N1BEE */
- (void) usprintf(scb->socket,count_rsp,scb->folder_len);
- scb->state = TRANS;
- return; /* no file = OK */
- }
-
- scb->folder_file_size = folder_stat.st_size;
- if ((fd = fopen(folder_pathname,"r")) == NULL){
- state_error(scb,"Unable to open mail folder");
- return;
- }
-
- if ((scb->wf = tmpfile()) == NULL) {
- state_error(scb,"Unable to create work folder");
- return;
- }
-
- scb->msg=calloc(sizeof(struct pop_msg),1); /* create first element */
- if (scb->msg==NULL)
- {
- fatal_error(scb,"Unable to create pointer list");
- return;
- }
- scb->msg->next=NULL;
- msg=scb->msg;
- msg->len=0;
- msg->deleted=0;
-
- while(!feof(fd)) {
- pos=ftell(scb->wf);
- fgets(line,TLINELEN,fd);
-
- /* scan for begining of a message */
-
- if (isSOM(line))
- {
- scb->folder_len++;
- msg->next=calloc(sizeof(struct pop_msg),1);
- if (msg->next==NULL)
- {
- fatal_error(scb,
- "Unable to create pointer list");
- return;
- }
- msg=msg->next;
- msg->pos=pos;
- msg->next=NULL;
- msg->len=0;
- msg->deleted=0;
-
- /* now put the line in the work file */
- }
- fputs(line,scb->wf);
- rrip(line);
- if ( *line == '.' ) msg->len++;
- msg->len +=strlen(line)+2; /* Add msg len count */
- }
-
- fclose(fd);
- scb->high_num=0; /* reset high read */
-
- (void) usprintf(scb->socket,count_rsp,scb->folder_len);
-
- scb->state = TRANS;
- }
-
- static void
- #ifdef PROTOTYPES
- stat_message(struct pop_scb *scb)
- #else
- stat_message(scb)
- struct pop_scb *scb;
- #endif
- {
- long total=0;
- int count=0;
- struct pop_msg *msg;
-
- if (scb == NULLSCB) /* check for null -- wa6smn */
- return;
-
- if (scb->folder_len) /* add everything up */
- for (msg=scb->msg->next; msg!=NULL; msg=msg->next)
- if (!msg->deleted)
- { total += msg->len; ++count;}
-
- (void) usprintf(scb->socket,stat_rsp,count,total);
- }
-
- static void
- #ifdef PROTOTYPES
- list_message(struct pop_scb *scb)
- #else
- list_message(scb)
- struct pop_scb *scb;
- #endif
- {
- struct pop_msg *msg;
- int msg_no=0;
- long total=0;
- #ifndef __TURBOC__
- static
- #endif
- struct pop_msg *goto_msg(struct pop_scb *,int );
-
- if (scb == NULLSCB) /* check for null -- wa6smn */
- return;
- if (scb->buf[sizeof(list_cmd) - 1] == ' ')
- {
- msg_no = atoi(&(scb->buf[sizeof(list_cmd) - 1]));
- msg=goto_msg(scb,msg_no);
- if (msg==NULL || msg->deleted)
- state_error(scb,"non existent or deleted message");
- else
- (void) usprintf(scb->socket,list_single_rsp,
- msg_no,msg->len);
- } else /* multiline */
- {
- if (scb->folder_len) /* add everything */
- for (msg=scb->msg->next; msg!=NULL;msg=msg->next)
- if (!msg->deleted)
- total += msg->len,++msg_no;
-
- (void) usprintf(scb->socket,list_multi_rsp,
- msg_no,total);
-
- if (scb->folder_len)
- for (msg=scb->msg->next,msg_no=1; msg!=NULL;
- msg=msg->next,msg_no++)
- if (!msg->deleted) {
- (void) usprintf(scb->socket,"%d %ld\n",
- msg_no,msg->len);
- }
- (void) usprintf(scb->socket,multi_end_rsp);
- }
- }
-
- static void
- #ifdef PROTOTYPES
- retr_message(struct pop_scb *scb)
- #else
- retr_message(scb)
- struct pop_scb *scb;
- #endif
- {
- char line[TLINELEN];
- long cnt;
- int msg_no;
- struct pop_msg *msg;
- #ifndef __TURBOC__
- static
- #endif
- struct pop_msg *goto_msg(struct pop_scb *,int );
-
- if (scb == NULLSCB) /* check for null -- wa6smn */
- return;
- if (scb->buf[sizeof(retr_cmd) - 1] != ' ')
- {
- state_error(scb,"no such message");
- return;
- }
- msg_no = atoi(&(scb->buf[sizeof(retr_cmd) - 1]));
- msg=goto_msg(scb,msg_no);
- if (msg==NULL || msg->deleted) {
- state_error(scb,"no such message");
- return;
- }
-
- cnt = msg->len;
- (void) usprintf(scb->socket,retr_rsp,cnt);
- fseek(scb->wf,msg->pos,SEEK_SET); /* Go there */
-
- while(!feof(scb->wf) && (cnt > 0)) {
- fgets(line,TLINELEN,scb->wf);
- rrip(line);
- if ( *line == '.' ) {
- (void) usprintf(scb->socket,".");
- cnt--;
- }
- (void) usputs(scb->socket,line);
- (void) usputc(scb->socket,'\n');
- cnt -= (strlen(line)+2); /* Compensate for CRLF */
- }
- (void) usprintf(scb->socket,".\n");
- if (msg_no >= scb->high_num)
- scb->high_num=msg_no; /* bump high water mark */
- }
-
- static void
- #ifdef PROTOTYPES
- noop_message(struct pop_scb *scb)
- #else
- noop_message(scb)
- struct pop_scb *scb;
- #endif
- {
- (void) usprintf(scb->socket,noop_rsp);
- }
-
- static void
- #ifdef PROTOTYPES
- last_message(struct pop_scb *scb)
- #else
- last_message(scb)
- struct pop_scb *scb;
- #endif
- {
- (void) usprintf(scb->socket,last_rsp,scb->high_num);
- }
-
- static void
- #ifdef PROTOTYPES
- rset_message(struct pop_scb *scb)
- #else
- rset_message(scb)
- struct pop_scb *scb;
- #endif
- {
- struct pop_msg *msg;
- long total=0;
-
- if (scb->folder_len)
- for (msg=scb->msg->next; msg!=NULL; msg=msg->next)
- msg->deleted=FALSE,total+=msg->len;
-
- scb->high_num=0; /* reset last */
- scb->folder_modified=FALSE;
- (void) usprintf(scb->socket,list_multi_rsp,scb->folder_len,total);
- }
-
- static void
- #ifdef PROTOTYPES
- top_message(struct pop_scb *scb)
- #else
- top_message(scb)
- struct pop_scb *scb;
- #endif
- {
- char *ptr;
- char line[TLINELEN];
- struct pop_msg *msg;
- int msg_no=0,lines=0;
- long total=0;
-
- #ifndef __TURBOC__
- static
- #endif
- struct pop_msg *goto_msg(struct pop_scb *,int );
-
- if (scb == NULLSCB) /* check for null -- wa6smn */
- return;
- if (scb->buf[sizeof(top_cmd) - 1] != ' ')
- {
- state_error(scb,"No message specified");
- return;
- }
- for (ptr=scb->buf+sizeof(top_cmd); *ptr==' ' ; ++ptr);
- /* Space drop */
- for ( ; *ptr!=' ' && *ptr !='\0'; ++ptr);
- /* token drop */
- msg_no = atoi(&(scb->buf[sizeof(top_cmd) - 1]));
- lines = atoi(++ptr); /* Get # lines to top */
- if (lines < 0) lines=0;
-
- msg=goto_msg(scb,msg_no);
- if (msg==NULL || msg->deleted)
- {
- state_error(scb,"non existent or deleted message");
- return;
- }
- fseek(scb->wf,msg->pos,SEEK_SET); /* Go there */
- total=msg->len; /* Length of current message */
- (void) usprintf(scb->socket,noop_rsp); /* Give OK */
- do {
- fgets(line,TLINELEN,scb->wf);
- rrip(line);
- if ( *line == '.' ) {
- (void) usprintf(scb->socket,".");
- total--;
- }
- total -= strlen(line)+2;
- (void) usputs(scb->socket,line);
- (void) usputc(scb->socket,'\n');
- } while (*line!='\0' && total>0);
- for ( ; total > 0 && lines; --lines) {
- fgets(line,TLINELEN,scb->wf);
- rrip(line);
- if ( *line == '.' ) {
- (void) usprintf(scb->socket,".");
- total--;
- }
- total -= strlen(line)+2;
- (void) usputs(scb->socket,line);
- (void) usputc(scb->socket,'\n');
- }
- (void) usprintf(scb->socket,multi_end_rsp);
- }
-
- static int
- poplogin(username,pass)
- char *pass;
- char *username;
- {
- char buf[80];
- char *cp;
- char *cp1;
- FILE *fp;
-
- if((fp = fopen(Popusers,"r")) == NULLFILE) {
- /* User file doesn't exist */
- tprintf("POP users file %s not found\n",Popusers);
- return(FALSE);
- }
-
- while(fgets(buf,sizeof(buf),fp),!feof(fp)) {
- if(buf[0] == '#')
- continue; /* Comment */
-
- if((cp = strchr(buf,':')) == NULLCHAR)
- /* Bogus entry */
- continue;
-
- *cp++ = '\0'; /* Now points to password */
- if(strcmp(username,buf) == 0)
- break; /* Found user name */
- }
-
- if(feof(fp)) {
- /* User name not found in file */
-
- fclose(fp);
- return(FALSE);
- }
- fclose(fp);
-
- if ((cp1 = strchr(cp,':')) == NULLCHAR)
- return(FALSE);
-
- *cp1 = '\0';
- if(strcmp(cp,pass) != 0) {
- /* Password required, but wrong one given */
-
- return(FALSE);
- }
-
- /* whew! finally made it!! */
-
- return(TRUE);
- }
-
- static void
- #ifdef PROTOTYPES
- dele_message(struct pop_scb *scb)
- #else
- dele_message(scb)
- struct pop_scb *scb;
- #endif
- {
- struct pop_msg *msg;
- int msg_no;
- #ifndef __TURBOC__
- static
- #endif
- struct pop_msg *goto_msg(struct pop_scb *,int );
-
- if (scb == NULLSCB) /* check for null -- wa6smn */
- return;
- if (scb->buf[sizeof(retr_cmd) - 1] != ' ')
- {
- state_error(scb,"no such message");
- return;
- }
- msg_no = atoi(&(scb->buf[sizeof(retr_cmd) - 1]));
- msg=goto_msg(scb,msg_no);
- if (msg==NULL || msg->deleted) {
- state_error(scb,"attempt to access deleted message");
- return;
- }
- if (msg->deleted) /* Don't bother if already dead */
- {
- state_error(scb,"message already deleted");
- return;
- }
- msg->deleted=TRUE;
- scb->folder_modified = TRUE;
- (void) usprintf(scb->socket,dele_rsp,msg_no);
- }
-
- static int
- #ifdef PROTOTYPES
- newmail(struct pop_scb *scb)
- #else
- newmail(scb)
- struct pop_scb *scb;
- #endif
- {
- char folder_pathname[64];
- struct stat folder_stat;
-
- sprintf(folder_pathname,"%s/%s.txt",Mailspool,scb->username);
-
- /* if (stat(folder_pathname,&folder_stat)) { */
- if((folder_stat.st_size = fsize(folder_pathname)) == -1) { /* N1BEE */
- state_error(scb,"Unable to get old mail folder's status");
- return(FALSE);
- } else
- return ((folder_stat.st_size > scb->folder_file_size)? TRUE:FALSE);
- }
-
- static struct pop_msg *
- goto_msg(struct pop_scb *scb,int msg_no)
- {
- int msg_num;
- struct pop_msg *msg;
-
- msg_num=msg_no-1;
- if (scb->folder_len==0 || msg_num < 0)
- return NULL;
- for (msg=scb->msg->next; msg_num && msg!=NULL; --msg_num) msg=msg->next;
- return msg;
- }
-
- #endif
-
-